package d2_final_exam.d5_fifth_question;

import java.io.*;
import java.net.Socket;
import java.util.Properties;

//1、继承Thread线程类,当前类成为一个线程类
public class ServerReaderThread extends Thread {
    //2、定义一个变量, 接当前与客户端接通的管道
    private Socket socket;

    public ServerReaderThread(Socket socket) {
        this.socket = socket;
    }

    //3、重写run()方法,编写服务端要为客户端实现的逻辑
    @Override
    public void run() {
        //4、首先获取管道的输入流,进行信息的读取 --> 使用特殊数据输入流进行读取
        try {
            DataInputStream dis = new DataInputStream(socket.getInputStream());
            //5、开始进行读取数据----- > 读取消息类型
            //一般用于做服务器 --> 保证服务器不死亡
            while (true) { //要进行反复的接受
                int flag = dis.readInt();
                //6、区分消息,做不同的处理
                switch (flag) {
                    case 1:
                        //注册
                        register();
                        break;
                    case 2:
                        //登录
                        login();
                        break;
                }
            }
        } catch (Exception e) { //使用父类异常,接受一切异常
            //这里可以追踪上下线逻辑
            System.out.println("有人里里线了");
        }
    }

    //实现注册的逻辑
    private void register() throws Exception {
        //1、用当前与客户端连接的管道,进行获取一个输入流 --------> 有异常就往上抛
        DataInputStream dis = new DataInputStream(socket.getInputStream());
        //2、然后进行接收客户端发送过来的注册名与密码
        String loginName = dis.readUTF();
        String password = dis.readUTF();
        //4、反馈的消息, 默认是注册成功的
        String result = "注册成功";
        //3、首先判断当前系统有没有-- > 这个用户名,(要求, 用户名是不可以重复的) --> 是用properties 属性文件进行存储用户名与密码
        //做成全自动化 --- > 文件是属于服务端,路径应该定义在,服务端
        if (exist(loginName)) {
            result = "您输出的用户名已经没被占用了, 注册失败";
        } else {
            //保存到属性文件中 --> 先创建一个属性文件集合
            Properties properties = new Properties();
            //现在开始保存密码用用户名 --> 存到集合中去
            properties.setProperty(loginName,password);
            properties.store(new FileWriter(Server.USER_FILE_PATH,true), "");//要进行追加
        }

        //最后再进行相应 --->  获取输出管道
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        dos.writeUTF(result);
        //进行反馈
        dos.flush();
    }

    private boolean exist(String loginName) throws Exception {
        //1.创建一个文件对象
        File file = new File(Server.USER_FILE_PATH);
        //2.要考虑文件不存在的情况
        if (file.exists()) {  // 可能有一种情况,是文件存在, 但是里面是空的
            //3.提取全部登录名看这个登录名是否已经存在
            Properties properties = new Properties();
            properties.load(new FileReader(Server.USER_FILE_PATH));
            //4.然后判断,等录名是否已经存在
            if (properties.containsKey(loginName)) {
                //证明是存在
                return true;
            }
        }
        return false;
    }

    /**
     * 实现登录的逻辑
     */
    private void login() throws Exception {
        //1.利用socket获取输入管道
        DataInputStream dis = new DataInputStream(socket.getInputStream());

        //2.接受用户名与密码
        String loginName = dis.readUTF();
        String password = dis.readUTF();
        //3.首先设置一个标志,进行反馈, 默认是等录成功的
        String result = "登录成功";
        File file = new File(Server.USER_FILE_PATH);
        //4.开始判断,属性文件是否存在
        if (file.exists()){
            //可以进行登录--> 校验密码
            Properties properties = new Properties();
            properties.load(new FileReader(Server.USER_FILE_PATH));
            String OkPassword = properties.getProperty(loginName);
            //然后判断是否存在
            if (OkPassword == null){
                result = "您的输入的用户名有误";
            }else {
                //开这里就开始校验密码
                if (!OkPassword.equals(password)){
                    result = "您输出的密码有误";
                }
            }
        }else {
            result = "当前系统一个用户也没用, 无法进行登录";
        }

        //5.然后得到一个输出流
        DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
        //进行反馈
        dos.writeUTF(result);
        dos.flush();

    }


}
